package org.example.ch06.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * @ClassName ProduceService
 * @Description TODO
 * @Author Kx
 * @Date 2025/10/14 11:04
 * @Version 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ProduceService {
    private final RabbitTemplate rabbitTemplate;

    /**
     * @author: kx
     * @date: 2025/10/14 11:05
     * @param message : 消息内容
     * @description: 消息确认投递到交换机
    */
    public void send(String message) {
        // 创建消息的唯一ID
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());
        // 投递消息
        rabbitTemplate.convertAndSend("test.exchange",".key.test",message,correlationData);

        // 通过一个回调来接收 rabbitmq 返回的 ack
        // 由于设置了 ConfirmCallback，因此消息只要到达 exchange，返回的 ack 就为 true
        rabbitTemplate.setConfirmCallback((cdata, ack, cause) -> {
            // 获取消息id
            String id = cdata.getId();
            if (!ack) {
                log.info("消息{}投递失败", id);
            } else {
                log.info("消息{}投递成功", id);
            }
        });
    }

    /**
     * @author: kx
     * @date: 2025/10/14 11:25
     * @param message : 消息内容
     * @description: 消息确认投递到队列中
    */
    public void send2(String message) {
        // 创建消息的唯一ID
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());
        // 投递消息
        rabbitTemplate.convertAndSend("test.exchange","key.test",message,correlationData);

        // 确认消息投递到队列中
        // 注意：只有消息未能正确到达队列时才会执行这个回调
        rabbitTemplate.setReturnsCallback(returnedMessage -> {
            log.info("消息内容：{}", new String(returnedMessage.getMessage().getBody(), StandardCharsets.UTF_8));
            log.info("确认码：{}", returnedMessage.getReplyCode());
            log.info("路由key：{}", returnedMessage.getRoutingKey());
        });
    }
}
